/*
    板子硬件情况定义，统一提供给APP或者其他驱动的名称
    GPIO的相关设置、模式切换建议定义在这里
*/
#ifndef _HARD_WIRED_H_
#define _HARD_WIRED_H_

#include "app_config.h"

#define BSP_MCU_MODEL POLSYS_MCU_CMS32F0301

// GPIO总初始化

// 所有IO口默认上拉输入 防止悬空
#define Gpio_Init()                                                                                                                    \
    {                                                                                                                                  \
        /* 端口输出电平 */                                                                                                       \
        GPIO0->DO = 0b11101101;                                                                                                        \
        GPIO1->DO = 0b10111111;                                                                                                        \
        GPIO2->DO = 0b11111001;                                                                                                        \
        GPIO3->DO = 0b11111011;                                                                                                        \
        GPIO4->DO = 0b11111111;                                                                                                        \
        /* 端口模式 0:浮空输入（默认） 1:推挽输出 2:开漏输出 3:上拉输入 4:下拉输入 5:上拉开漏输出 */ \
        GPIO0->PMS = (1 << 28) | (1 << 24) | (1 << 20) | (1 << 16) | (3 << 12) | (3 << 8) | (1 << 4) | (0 << 0);                       \
        GPIO1->PMS = (1 << 28) | (1 << 24) | (4 << 20) | (3 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | (3 << 0);                       \
        GPIO2->PMS = (3 << 28) | (1 << 24) | (1 << 20) | (4 << 16) | (3 << 12) | (1 << 8) | (1 << 4) | (3 << 0);                       \
        GPIO3->PMS = (3 << 28) | (0 << 24) | (1 << 20) | (3 << 16) | (3 << 12) | (1 << 8) | (4 << 4) | (3 << 0);                       \
        GPIO4->PMS = (1 << 28) | (0 << 24) | (3 << 20) | (3 << 16) | (3 << 12) | (3 << 8) | (3 << 4) | (3 << 0);                       \
        /* 端口模式 数字(默认)，通过IO口可复用为模拟  */                                                             \
        /* 驱动能力 0:高 1:低（默认） */                                                                                     \
        GPIO0->DR = 0b11111111;                                                                                                        \
        GPIO1->DR = 0b11111111;                                                                                                        \
        GPIO2->DR = 0b11111111;                                                                                                        \
        GPIO3->DR = 0b11011111;                                                                                                        \
        GPIO4->DR = 0b11111111;                                                                                                        \
        /* 驱动速度 0:高 1:低（默认） */                                                                                     \
        GPIO0->SR = 0b11111111;                                                                                                        \
        GPIO1->SR = 0b11111111;                                                                                                        \
        GPIO2->SR = 0b11111111;                                                                                                        \
        GPIO3->SR = 0b11011111;                                                                                                        \
        GPIO4->SR = 0b11111111;                                                                                                        \
        /* 开启IO口中断 0:关闭（默认） 1:开启 */                                                                          \
        GPIO0->IMSC = 0b00000000;                                                                                                      \
        GPIO1->IMSC = 0b00000000;                                                                                                      \
        GPIO2->IMSC = 0b00000000;                                                                                                      \
        GPIO3->IMSC = 0b00000000;                                                                                                      \
        GPIO4->IMSC = 0b00000000;                                                                                                      \
        /* IO口中断触发模式 0:下降沿（默认）或者上升沿（由IVAL决定） 1:下降沿和上升沿 */                \
        GPIO0->IANY = 0b11111111;                                                                                                      \
        GPIO1->IANY = 0b11111111;                                                                                                      \
        GPIO2->IANY = 0b11111111;                                                                                                      \
        GPIO3->IANY = 0b11111111;                                                                                                      \
        GPIO4->IANY = 0b11111111;                                                                                                      \
    }

// IO口复用配置
// SYS_SET_IOCFG(IOP16CFG, SYS_IOCFG_P16_GPIO);

// SPI FLASH
#define FLASH_CS_PIN_OUT GPIO2->DO_f.P5

// SPI LCD
#define LCD_CS_PIN_OUT  GPIO0->DO_f.P5
#define LCD_RST_PIN_OUT GPIO0->DO_f.P6
#define LCD_DC_PIN_OUT  GPIO0->DO_f.P7

// 软件模拟
// #define LCD_USE_SOFTSPI
#define SPI_CLK_PIN_OUT  GPIO2->DO_f.P6
#define SPI_MOSI_PIN_OUT GPIO4->DO_f.P7

// // 硬件PWM初始化 LED + OUT
// #define HPwm_Init()                         \
//     {                                       \
//         AdvTim_Tim4Init();                  \
//         M0P_ADTIM4->GCMCR = TIM4_CYCLE / 2; \
//         AdvTim_Tim6Init();                  \
//     }

// Pca_Init();            \
        // M0P_PCA->CCAP2H = 128; \

// 机械按键
#define BUTON_PIN_IN       GPIO3->DI_f.P4
#define ENABLE_BUTTON_INT  (GPIO3->IMSC |= (1 << 4))
#define DISABLE_BUTTON_INT (GPIO3->IMSC &= ~(1 << 4))

// 电容采集
#ifdef _APP_USE_TOUCH_KEY

// TOUCH VLOAD
#define VLOAD_INIT  /
#define VLOAD       M0P_GPIO->P3OUT_f.P33
#define VLOAD_OUT_H VLOAD = 1
#define VLOAD_OUT_L VLOAD = 0

// TOUCH CH0 咪头/触摸键
#define TCH0_PIN_IN       M0P_GPIO->P3IN_f.P34
#define TCH0_PIN_OUT_PP   M0P_GPIO->P3DIR_f.P34 = 0
#define TCH0_PIN_OUT      M0P_GPIO->P3OUT_f.P34
#define TCH0_PIN_IN_HZ    M0P_GPIO->P3DIR_f.P34 = 1
#define TCH0_PIN_FUN_GPIO GPIO_P34_SEL_GPIO_P34
#define TCH0_PIN_FUN_CAP  GPIO_P34_SEL_TIM5_CHA

#if _APP_CAPSS_CH_NUM >= 2
// TOUCH CH1 触摸
#define TCH1_PIN_IN       M0P_GPIO->P3IN_f.P33
#define TCH1_PIN_OUT_PP   M0P_GPIO->P3DIR_f.P33 = 0
#define TCH1_PIN_OUT      M0P_GPIO->P3OUT_f.P33
#define TCH1_PIN_IN_HZ    M0P_GPIO->P3DIR_f.P33 = 1
#define TCH1_PIN_FUN_GPIO GPIO_P33_SEL_GPIO_P33
#define TCH1_PIN_FUN_CAP  GPIO_P33_SEL_TIM5_CHB

#endif

#else
// 有源咪头
#define MIC_PIN_IN      GPIO3->DI_f.P1
#define ENABLE_MIC_INT  (GPIO3->IMSC |= (1 << 1))
#define DISABLE_MIC_INT (GPIO3->IMSC &= ~(1 << 1))

#endif

// ANSEL11 ANS11
#define OVAL_PIN_IN         GPIO3->DI_f.P6
#define OVAL_ANALOG_MODE    SYS_SET_IOCFG(IOP36CFG, SYS_IOCFG_P36_AN24)
#define OVAL_DIGIT_MODE     SYS_SET_IOCFG(IOP36CFG, SYS_IOCFG_P36_GPIO)
#define OVAL_PULL_UP        GPIO1->DO_f.P6 = 1
#define OVAL_PULLUP_IS_OPEN GPIO1->DI_f.P6
#define OVAL_PULL_DOWN      GPIO1->DO_f.P6 = 0
#define OVAL_PULL_OFF

// OVAL中断
#define ENABLE_OVAL_INT  (GPIO3->IMSC |= (1 << 6))
#define DISABLE_OVAL_INT (GPIO3->IMSC &= ~(1 << 6))

// 通讯唤醒端口
#define ENABLE_RX_INT  // GPIO_FIE_ENABLE(GPIO_PORT_1, 5)
#define DISABLE_RX_INT // GPIO_FIE_DISABLE(GPIO_PORT_1, 5)

// 串口IO初始化和反初始化
#define UART1_IO_INIT                                \
    {                                                \
        SYS_SET_IOCFG(IOP23CFG, SYS_IOCFG_P23_RXD1); \
        SYS_SET_IOCFG(IOP24CFG, SYS_IOCFG_P24_TXD1); \
    }
#define UART1_IO_DEINIT                                   \
    {                                                     \
        SYS_SET_IOCFG(IOP23CFG, SYS_IOCFG_P23_SWDDAT1);   \
        SYS_SET_IOCFG(IOP24CFG, SYS_IOCFG_P24_SWDCLK1_0); \
    }

// USB充电检测端口
#define DCIN_PIN_IN      GPIO1->DI_f.P5
#define USB_IS_IN        (DCIN_PIN_IN)
#define ENABLE_DCIN_INT  (GPIO1->IMSC |= (1 << 5))
#define DISABLE_DCIN_INT (GPIO1->IMSC &= ~(1 << 5))

// 输出控制引脚
#define OUTEN_PIN_OUT GPIO3->DO_f.P5
#define OUTEN_PIN_IN  GPIO3->DI_f.P5
#define OUTEN_ON      OUTEN_PIN_OUT = 0
#define OUTEN_OFF     OUTEN_PIN_OUT = 1
#define OUTEN_IS_ON   (OUTEN_PIN_IN == 0)
#define OUTEN_GPIO    SYS_SET_IOCFG(IOP35CFG, SYS_IOCFG_P35_GPIO)
#define OUTEN_HPWM    SYS_SET_IOCFG(IOP35CFG, SYS_IOCFG_P35_CCP0B)
#define OUTEN_PWM_CH  M0P_ADTIM6->GCMCR

// 外设总电源控制引脚
#define VEXT_PIN_OUT GPIO1->DO_f.P7
#define VEXT_ON      VEXT_PIN_OUT = 0
#define VEXT_OFF     VEXT_PIN_OUT = 1

// LCD背光控制，注意：需要开启总电源后，控制才有效
#define LCD_BG_PIN_OUT GPIO0->DO_f.P1
#define LCD_BG_ON      LCD_BG_PIN_OUT = 1
#define LCD_BG_OFF     LCD_BG_PIN_OUT = 0

// LCD电源控制，仅仅供电VDD，注意：开启背光后才能真正显示
#define LCD_VDD_PIN_OUT GPIO0->DO_f.P4
#define LCD_VDD_ON      LCD_VDD_PIN_OUT = 1
#define LCD_VDD_OFF     LCD_VDD_PIN_OUT = 0

// 电流检测IC电源控制
#define DIV_VDD_PIN_OUT  GPIO2->DO_f.P1
#define DIV_VDD_PIN2_OUT GPIO2->DO_f.P2
#define DIV_VDD_ON            \
    {                         \
        DIV_VDD_PIN_OUT = 1;  \
        DIV_VDD_PIN2_OUT = 1; \
    }
#define DIV_VDD_OFF           \
    {                         \
        DIV_VDD_PIN_OUT = 0;  \
        DIV_VDD_PIN2_OUT = 0; \
    }

// 电流IO配置
#define DIV_ANALOG_MODE SYS_SET_IOCFG(IOP13CFG, SYS_IOCFG_P13_AN8)

// 当不通过USB和螺纹检测充电时，另外需要检测是否处于充电状态，则定义本端口(DCIN)
#if (!defined _APP_USE_USB_CHARGE_LED) && (!defined _APP_USE_LW_CHARGE_LED)
#define CHARGE_DOING _IO_DCIN
#endif

#define ADCH_OVAL 24
#define ADCH_DIV  8

// 清除标记，开启唤醒中断
#define WakeUp_Enable()           \
    {                             \
        /* 清除中断标记 */  \
        GPIO0->ICLR = 0xFF;       \
        GPIO1->ICLR = 0xFF;       \
        GPIO2->ICLR = 0xFF;       \
        GPIO3->ICLR = 0xFF;       \
        /* 开启唤醒中断     \
        ENABLE_DCIN_INT;          \
        ENABLE_BUTTON_INT;        \
        ENABLE_OVAL_INT;       */ \
    }

// 关闭唤醒中断
#define WakeUp_Disable()         \
    {                            \
        /* 关闭唤醒中断 */ \
        DISABLE_DCIN_INT;        \
        DISABLE_BUTTON_INT;      \
        DISABLE_OVAL_INT;        \
    }

#endif
